<template>
  <f7-app :params="f7params">
    <f7-view main style="z-index: 1000" v-if="!pageLoading">
      <fm-generate-form
        :data="JSON.parse(controlData.designData)"
        :remote="remoteFuncs"
        v-model="models"
        :pageAction="pageAction"
        ref="smartform"
        :objectKey="objectKey"
        @loaded="loadDone"
      >
        <template v-slot:inner>
          <div v-html="vHtml"></div>
        </template>
      </fm-generate-form>
    </f7-view>
    <iframe ref="smartform_jsframe" name="smartform_jsframe" v-show="false"></iframe>
  </f7-app>
</template>

<script>
import App from "@/App.vue";
import controller from "@/libs/framework/controller";
import _ from "lodash";
import Injection from "@/libs/framework/injection";
export default class instance extends controller {
  onBeforeInit() {
    this.urls = {
      model: "/smartform/mobile/hub/",
      save: "/smartform/save",
    };
  }
  onInit() {
    let pageId = this.vm.pageId;
    let pageCode = this.vm.pageCode || this.$params.pageCode;
    let version = this.vm.version;
    let pkey = this.vm.pkey;

    let url = `/smartform/mobile/hub/${pageCode}`;
    this.urls.model = url;

    if (pageId) {
      this.setRequestParam("pageId", pageId, "form");
    }
    if (version) {
      this.setRequestParam("version", version, "form");
    }
    if (pkey) {
      _.each(pkey, (v, k) => {
        this.setRequestParam(k, v, "form");
      });
    }
  }

  onAfterQuery(type, isSuccess, result) {
    if (isSuccess) {
      // if (result.enums) {
      //   this.vm.$root.enums = result.enums;
      // }
      // if (result.dicts) {
      //   this.vm.$root.dicts = result.dicts;
      // }
      // if (result.controlData) {
      //   this.vm.$root.controlData = result.controlData;
      // }
      if (result.models && result.models.model) {
        let datakey = result.models.model["datakey"];
        result.models.model["datakey"] = datakey || Math.uuid();
      }
    }
    this.vm.loadJs(result);
    this.vm.loadVueMethod(result);

    return result;
  }

  mixin() {
    return {
      props: {
        // 表单相关
        pageId: String,
        pageCode: String,
        version: String | Number,
        // 工作流相关
        appCode: String,
        taskId: String,
        historyTaskId: String,
        assigneeId: String,
        // 主键
        pkey: Object,
      },
      data() {
        return {
          pageLoading: false,
          controlData: {
            formTables: [],
            tableColumns: [],
            tables: [],
            designData: `{
              "list": [],
              "f7list": [],
              "config": {
                "labelWidth": 100,
                "labelPosition": "right",
                "size": "small",
                "customClass": "",
                "ui": "framework7",
                "layout": "horizontal",
                "labelCol": 3
              },
              "page": {
                "pageId": "",
                "title": "",
                "onVueCreated": "",
                "onVueMounted": ""
              },
              "f7page": {
                "pageContent": true,
                "hideNavbarOnScroll": false,
                "hideToolbarOnScroll": false,
                "ptr": true,
                "infinite": true,
                "onVueCreated": "",
                "onVueMounted": ""
              }
            }`,
          },
          primaryKey: {},
          pageAction: "create",
          jsonData: {},
          editData: {},
          remoteFuncs: {},
          formName: "smartform",
          enums: {},
          dicts: {},
          models: {
            model: {},
          },
          vHtml: "",
          f7params: {
            routes: [
              {
                path: "/smartform/mobileRender",
                component: App,
              },
            ],
            iosTranslucentBars: false, // 半透明禁用
            iosTranslucentModals: false,
            dialog: {
              title: "温馨提示",
              buttonOk: "确定",
              buttonCancel: "取消",
              preloaderTitle: "加载中... ",
              progressTitle: "加载中... ",
            },
            searchbar: {
              placeholder: "搜索",
              disableButtonText: "取消",
            },
            smartSelect: {
              pageBackLinkText: "返回",
              popupCloseLinkText: "关闭",
              sheetCloseLinkText: "确定",
              searchbarPlaceholder: "搜索",
              searchbarDisableText: "取消",
            },
            autocomplete: {
              openIn: "popup",
              limit: 50,
              requestSourceOnOpen: true,
              preloader: true,
              pageBackLinkText: "返回",
              popupCloseLinkText: "关闭",
              searchbarPlaceholder: "输入关键字搜索",
              searchbarDisableText: "取消",
              notFoundText: "没有找到相关记录",
            },
            picker: {
              toolbarCloseText: "确定",
            },
            calendar: {
              headerPlaceholder: "选择日期",
              timePickerPlaceholder: "选择时间",
              toolbarCloseText: "确定",
            },
            photoBrowser: {
              pageBackLinkText: "返回",
              popupCloseLinkText: "关闭",
              sheetCloseLinkText: "完成",
              theme: "dark",
              navbar: true,
              toolbar: true,
              navbarOfText: "/",
            },
            touch: {
              disableContextMenu: false, // 默认为false
            },
          },
          objectKey: "",
        };
      },
      methods: {
        getData() {
          return this.$refs.smartform.getData();
        },
        saveThenReload() {
          let self = this;
          // 只有最初一次新增时保存之后才重新加载数据
          if (self.pageAction != "create") {
            return;
          }
          self.$f7.dialog.preloader("数据加载中");
          let storeId = self.models.model.storeId;
          let pageCode = self.models.model.formCode;

          let url = `/smartform/mobile/edit/${pageCode}`;
          self.super.urls.model = url;

          self.super.$f7route.query.storeId = storeId;

          self.getViewModel().then(() => {
            self.$f7.dialog.close();
          });
        },
        loadVueMethod(result) {
          let vueMethod = {};
          let frameWindow = this.$refs.smartform_jsframe.contentWindow;

          if (
            result &&
            result.controlData &&
            result.controlData.vueMethod &&
            frameWindow
          ) {
            let vMetText = result.controlData.vueMethod;
            if (!vMetText.startsWith("{")) {
              vMetText = "{" + vMetText + "}";
            }

            vueMethod = JSON.stringify(vMetText, function (key, val) {
              if (typeof val === "function") {
                return val + "";
              }
              return val;
            });
            vueMethod = JSON.parse(vueMethod, function (k, v) {
              if (v.indexOf && v.indexOf("function") > -1) {
                return frameWindow.eval("(function(){return " + v + " })()");
              }
              return v;
            });
          }

          _.each(vueMethod, (value, key) => {
            if (typeof value === "function") {
              this[key] = function () {
                return value(...arguments);
              };
            }
          });
        },
        loadJs(result) {
          result = result || { controlData: {} };
          // 该 htmlClear 方法有问题，希望开发人员写的js不要有XSS风险
          // let js = this.super.$util.htmlClear(result.controlData.jsCode || "");
          let js = result.controlData.jsCode || "";

          let frameWindow = this.$refs.smartform_jsframe.contentWindow;
          if (frameWindow) {
            frameWindow.vue = this;
            frameWindow.data = result;
            Injection.injectSmartformJs(frameWindow);

            const s = frameWindow.document.createElement("script");
            s.type = "text/javascript";
            s.innerHTML = `${js}`;
            frameWindow.document.body.appendChild(s);
          }

          this.objectKey = Math.uuid();
          window[this.objectKey] = frameWindow;
        },
        loadCss() {
          let h = this.super.$util.htmlClear(this.controlData.cssCode || "");
          this.vHtml = `<style> ${h} </style>`;
        },
        loadWatchProp() {
          let watchProp = {};
          let frameWindow = this.$refs.smartform_jsframe.contentWindow;

          if (this.controlData.watchProp && frameWindow) {
            let wpText = this.controlData.watchProp;
            if (!wpText.startsWith("{")) {
              wpText = "{" + wpText + "}";
            }

            watchProp = JSON.stringify(wpText, function (key, val) {
              if (typeof val === "function") {
                return val + "";
              }
              return val;
            });

            watchProp = JSON.parse(watchProp, function (k, v) {
              if (v.indexOf && v.indexOf("function") > -1) {
                return frameWindow.eval("(function(){return " + v + " })()");
              }
              return v;
            });
          }

          let self = this;

          _.each(watchProp, (value, key) => {
            this.$watch(key, function (newVal, oldVal) {
              if (typeof value === "function") {
                value(newVal, oldVal, self);
              }
            });
          });
        },

        loadDone() {
          this.loadCss();
          this.loadWatchProp();

          let $smartform = this.$refs["smartform"];
          // if (
          //   $smartform.data.f7page.onVueCreated &&
          //   this.$root[$smartform.data.f7page.onVueCreated]
          // ) {
          //   this.$root[$smartform.data.f7page.onVueCreated](
          //     $smartform.$refs["f7GenerateForm"]
          //   );
          // }

          // if (
          //   $smartform.data.f7page.onVueMounted &&
          //   this.$root[$smartform.data.f7page.onVueMounted]
          // ) {
          //   this.$root[$smartform.data.f7page.onVueMounted](
          //     $smartform.$refs["f7GenerateForm"]
          //   );
          // }
          if (this.pageAction === "view") {
            $smartform.disabled("all", true);
          }
        },
      },

      created() {
        let self = this;

        this.getModels = function () {
          return self.$refs.smartform.models;
        };

        this.appendPrimaryKey = function (url, model) {
          if (!model) return url;
          for (var o in model) {
            var joinChar = url.indexOf("?") == -1 ? "?" : "&";
            url += joinChar;
            url += o + "=" + encodeURI(model[o] || "");
          }
          return url;
        };

        this.save = function () {
          self.$refs.smartform
            .getData()
            .then((d) => {
              var postModel = d;
              postModel.pageAction = self.pageAction;
              var url = self.appendPrimaryKey(self.urls.save, self.primaryKey);

              if (
                self.onBeforeSave &&
                self.onBeforeSave(postModel, url) === false
              ) {
                return;
              }
              self.$f7.dialog.preloader("正在保存");
              self.$f7.request.promise
                .post(url, postModel, "json")
                .then(function (rlt) {
                  rlt = rlt.data;
                  self.$f7.dialog.close();
                  if (
                    self.onAfterSave &&
                    self.onAfterSave(rlt, postModel) !== true
                  ) {
                    return;
                  }
                  if (rlt && rlt.success) {
                    self.$f7.dialog.alert(rlt.message || "保存成功！", () => {
                      self.saveThenReload();
                    });
                  } else {
                    rlt = rlt || {};
                    self.$f7.dialog.alert(rlt.message || "保存失败！");
                  }
                })
                .catch(function (e) {
                  console.error(e);
                  self.$f7.dialog.close();
                  self.$f7.dialog.alert(rlt.message || "保存失败！");
                });
            })
            .catch((e) => {
              self.$f7.dialog.alert("表单校验未通过！");
              console.error(e);
              return false;
            });
        };

        this.$root.getUploadApis = function () {
          return {
            downUrl: "/mobileApi/base/fileupload/downFile",
            getUrl: "/mobileApi/base/fileupload/getFiles",
            deleteUrl: "/mobileApi/base/fileupload/delFile",
            postUrl: "/mobileApi/base/fileupload/uploadFile",
          };
        };
      },
      mounted() {
        this.$once("hook:beforeDestroy", () => {
          if (this.objectKey) {
            window[this.objectKey] = null;
          }
        });
      },
      activated() {
        this.loadJs(this.$data);
        this.loadVueMethod(this.$data);
      },
    };
  }
}
</script>

<style scoped>
</style>
